home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!mcnc!rutgers!ukma!cwjcc!hal!ncoast!allbery
- From: ckern@killer.Dallas.TX.US (Chris Kern)
- Newsgroups: comp.sources.misc
- Subject: v05i062: another "last" -- this one is PD
- Message-ID: <8811202058.AA00164@ncoast.UUCP>
- Date: 26 Nov 88 23:23:51 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: ckern@killer.Dallas.TX.US (Chris Kern)
- Lines: 227
- Approved: allbery@ncoast.UUCP
-
- Posting-number: Volume 5, Issue 62
- Submitted-by: "Chris Kern" <ckern@killer.Dallas.TX.US>
- Archive-name: pd-last
-
- I don't like to complain about any source offering, and certainly
- the copyright holder of any code has a right to impose
- limitations on its use, but I thought Harvey Moran's restrictions
- on his Berkeley `last' look-alike were excessively severe. Taken
- at face value, they would prevent an administrator of several
- systems from installing an executable on each system and
- archiving the source on only one machine. ("The source code in
- machine readable format [must be] included with any binary
- distribution.")
-
- Anyway, at the risk initiating "source wars" (hmmm, better
- perhaps than "flame wars"), I'm enclosing a version of last.c
- that I wrote a couple of years ago for our System V machines. Its
- output is slightly different from Harvey's, and it is even less
- Berkeley compatible (although, if someone insists on "still
- logged in" as an alternative to not showing the logout time, the
- change would be easy to make), but it is not encumbered with
- restrictions of any kind. I have placed the code in the public
- domain.
-
- Any replies should be directed to my account ckern@killer, since
- voa3 is not currently on the net.
-
- Cheers,
-
- Chris Kern
-
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- #
- # Wrapped by ck on Sun Nov 20 14:54:34 EST 1988
- # Contents: last.c last.1
-
- echo x - last.c
- sed 's/^XX//' > "last.c" <<'@//E*O*F last.c//'
- XX#include <stdio.h>
- XX#include <sys/types.h>
- XX#include <string.h>
- XX#include <time.h>
- XX#include <utmp.h>
-
-
- XX#define OWTMP_FILE "/usr/adm/acct/nite/owtmp" /* file to search after /etc/wtmp */
-
- XXstatic char *prog;
- XXstatic char *wtmpfile[] = { OWTMP_FILE, WTMP_FILE, NULL };
-
- XXstruct list {
- XX struct utmp rec;
- XX struct list *next;
- XX struct list *previous;
- XX};
-
-
-
- XXmain(argc, argv) /* last: show recent logins in last-to-first order */
- XXint argc;
- XXchar *argv[];
- XX{
- XX int i;
- XX void prproc();
- XX struct list *listp = NULL, *p, *addlist();
- XX struct utmp *entry;
- XX extern void utmpname();
- XX extern struct utmp *getutent();
-
- XX prog = argv[0];
-
- XX for (i = 0; wtmpfile[i] != NULL; i++) {
- XX utmpname(wtmpfile[i]);
- XX while ((entry = getutent()) != NULL)
- XX listp = addlist(listp, entry);
- XX }
-
- XX /* listp points to most recent wtmp entry */
-
- XX for (p = listp; p != NULL; p = p->previous)
- XX if (p->rec.ut_type == USER_PROCESS) {
- XX if (argc == 1)
- XX prproc(p, listp);
- XX else
- XX for (i = 1; i < argc; i++) {
- XX if (strcmp(p->rec.ut_user, argv[i]) == 0) {
- XX prproc(p, listp);
- XX break;
- XX }
- XX }
- XX }
-
- XX return (0);
- XX}
-
-
-
- XXstruct list *addlist(head, wtmp) /* add new wtmp entry to head of list */
- XXstruct list *head;
- XXstruct utmp *wtmp;
- XX{
- XX void errexit();
- XX register struct list *new;
- XX extern char *malloc();
-
- XX if ((new = (struct list *) malloc(sizeof(struct list))) == NULL)
- XX errexit("memory error", NULL);
- XX else {
- XX new->rec = *wtmp;
- XX new->next = new; /* no next yet */
- XX new->previous = head;
- XX if (head != NULL)
- XX head->next = new;
- XX }
- XX return (new);
- XX}
-
-
-
- XXvoid prproc(start, last) /* print entries for process */
- XXstruct list *start, *last;
- XX{
- XX void prentry();
- XX register struct list *p;
-
- XX prentry(start->rec);
- XX for (p = start->next; p != last; p = p->next)
- XX if (p->rec.ut_pid == start->rec.ut_pid)
- XX prentry(p->rec);
- XX putchar('\n');
- XX}
-
-
- XX
- XXvoid prentry(wtmp) /* print wtmp entry */
- XXstruct utmp wtmp;
- XX{
- XX static char *wkday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
- XX static char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
- XX char line[12 + 1], user[8 + 1]; /* magic numbers courtesy of /usr/include/utmp.h */
- XX struct tm *time;
- XX extern struct tm *localtime();
-
- XX strncpy(line, wtmp.ut_line, 12);
- XX strncpy(user, wtmp.ut_user, 8);
- XX line[12] = user[8] = '\0';
- XX time = localtime(&wtmp.ut_time);
- XX switch (wtmp.ut_type) {
- XX case USER_PROCESS:
- XX printf("%-8s %-12s %s %s %2d %02d:%02d",
- XX user, line, wkday[time->tm_wday], month[time->tm_mon], time->tm_mday, time->tm_hour, time->tm_min);
- XX break;
- XX case DEAD_PROCESS:
- XX printf(" - %02d:%02d %s", time->tm_hour, time->tm_min, wkday[time->tm_wday]);
- XX break;
- XX default:
- XX sprintf(line, "%d", wtmp.ut_type);
- XX errexit("illegal wtmp.ut_type entry:", line);
- XX }
- XX}
-
-
-
- XXvoid errexit(s1, s2) /* print error message and die */
- XXchar s1[], s2[];
- XX{
- XX extern void exit();
-
- XX fprintf(stderr, s2 == NULL ? "%s: %s\n" : "%s: %s %s\n", prog, s1, s2);
- XX exit(-1);
- XX}
- @//E*O*F last.c//
- chmod u=rw,g=r,o=r last.c
-
- echo x - last.1
- sed 's/^XX//' > "last.1" <<'@//E*O*F last.1//'
- XX.TH LAST 1 VOA
- XX.SH NAME
- XXlast \- show recent logins in last-to-first order
- XX.SH SYNOPSIS
- XX.B last
- XX[
- XXuser ...
- XX]
- XX.SH DESCRIPTION
- XX.I Last
- XXdisplays recent login and logout times
- XXin last-to-first order.
- XXIf invoked with
- XX.IR user s,
- XXoutput is restricted
- XXto the login and logout times
- XXof the specified account(s).
- XX.SH FILES
- XX.TP 30
- XX/etc/wtmp
- XXcurrent accounting file
- XX.TP 30
- XX/usr/adm/acct/nite/owtmp
- XXprevious day's accounting file
- XX.SH BUGS
- XXCertain types of system errors
- XXwill result in
- XX.I last
- XXfailing to report
- XXa user's logout time.
- @//E*O*F last.1//
- chmod u=rw,g=r,o=r last.1
-
- echo Inspecting for damage in transit...
- temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
- trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
- cat > $temp <<\!!!
- 134 418 2944 last.c
- 30 88 522 last.1
- 164 506 3466 total
- !!!
- wc last.c last.1 | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
- if test -s $dtemp
- then echo "Ouch [diff of wc output]:" ; cat $dtemp
- else echo "No problems found."
- fi
- exit 0
-